<template>
    <div class="page page-map-3d">
        <!--
            showGUI
        -->
        <v-3d-map ref="map" :rotatable="settings.rotatable" :opacity="settings.opacity" :mergedGeometry=false
            :offset="settings.offset || undefined" :camera="settings.camera" :axesHelper="500" :sky="settings.sky"
            :floor="settings.floor" :gridHelper="settings.gridHelper" :effect="settings.effect" :outlinePassable="settings.outlinePassable"
            :showAlarm="settings.showAlarm" :selectable="settings.selectable" :instancedMesh="settings.instancedMesh"
            :showStats=false :showLabels="settings.showLabels" :rotationSpeed="0.0005" :light="settings.light" showCameraHelper
            :followVehicle="followVehicle" :clickCallback="clickCallback"
            :pointerMoveCallback="pointerMoveCallback"></v-3d-map>
        <!-- <p-toolbar-map v-model="settings" :format="settingsFormat" :mapRef="$refs.map"></p-toolbar-map> -->
        <el-drawer v-model="drawer" title="I am the title" :direction="rtl" :before-close="handleClose">
            <span>Hi, there!</span>
        </el-drawer>
        <el-card class="box-card">
            <template #header>
                <div class="card-header">
                    <span>车道信息</span>
                </div>
            </template>
            <div class="text item">路段ID：{{ currRoadId }}</div>
            <div class="text item">车道ID：{{ currLaneId }}</div>
        </el-card>
    </div>
</template>
<script type="text/ecmascript-6">
import * as mock from '../mock/index.js';
import App from '../utils/3D/App.js';
import Kernel from '../core/Kernel.js';
import v3dMap from '../utils/3D/v-3d-map.vue';
import Storage from '../utils/Storage.js';
import offlineWorker from '../../workers/offline.worker.js';
import pToolbarMap from '../components/p-toolbar-map.vue';
import { GRAPH_TYPES } from '../utils/Graph/Graph.enum.js';
import { ref } from 'vue'
import { ElNotification } from 'element-plus'

export default {
    name: 'demo',
    components: { v3dMap, pToolbarMap },
    inject: ['reload'],
    data() {
        return {
            // offset: { x: -62000, y: -56000 },
            // offset: { x: -190000, y: -80000 },
            // camera: { x: -50, y: 30, z: 70, helper: true },
            // sky: null
            // light: { skyColor: 0xffffff, groundColor: 0x000000, intensity: 0.75, hIntensity: 0.2, pos: { x: -100, y: 200, z: 0 }, shadow: { far: 300, width: 16384, height: 16384 } },
            // sky: {},
            // showLabels: false,
            drawer: ref(false),
            followVehicle: '',
            currRoadId: '',
            currLaneId: '',
            settings: {
                topView: false,
                rotatable: false,
                resetHandler: this.handleReset,
                destoryHandler: this.handleDestory,
                showAlarm: true,
                showLabels: true,
                followVehicle: this.handleTarget,
                offset: { x: -190000, y: -80000, z: 0 },
                // camera: { x: -50, y: 30, z: 70, helper: true },
                camera: { x: -160, y: 50, z: 80, helper: true },
                //light: { skyColor: 0xffffff, groundColor: 0x000000, intensity: 0.75, hIntensity: 0.2, pos: { x: -100, y: 200, z: 0 }, shadow: { far: 300, width: 16384, height: 16384 } },
                light: { skyColor: '#ffffff', groundColor: '#000000', intensity: 0.75, hIntensity: 0.2, pos: { x: -100, y: 200, z: 0 }, shadow: { far: 300, width: 16384, height: 16384 } },
                sky: { enable: true, turbidity: 10, rayleigh: 0.8, mieCoefficient: 0.005, mieDirectionalG: 0.8, exposure: 0.5, inclination: 0, azimuth: 0.25 },
                floor: { width: 5000, height: 5000, color: '#8B8989', },
                gridHelper: { enable: false, w: 5000, n: 5000, cc: '#000000', gc: '#000000', opacity : 1},
                // bloomStrength decided bloomPass enable or not, edgeStrength  decided outlinePass enable or not.
                effect: { exposure: 1, bloomStrength: 0.25, bloomThreshold: 0.1, bloomRadius: 0.8, edgeStrength: 6, edgeGlow: 2, edgeThickness: 2, pulsePeriod: 1, usePatternTexture: false, visibleEdgeColor: '#ffff00', hiddenEdgeColor: '#190a05' },
                outlinePassable: true,
                selectable: true,
                instancedMesh: false,
                viewType: Storage.getSessionStorage('TINYENGINE').get('SETTINGS').viewType || '3D',
                opacity: 1
            },
            contoursCameraPos: {
                '445': { x: 0, y: 20, z: -50 },
                '273': { x: 0, y: 50, z: -50 },
                '373': { x: 0, y: 50, z: -50 },
                '439': { x: 0, y: 50, z: -50 },
                '413': { x: 0, y: 50, z: -50 },
            },
            trayDetail: {
                str: ''
            },
            trayDetailVisible: false
            // viewport: {}
        };
    },
    watch: {
        settings: {
            handler(val) {
                Storage.getSessionStorage('TINYENGINE').set('SETTINGS', val);
            },
            deep: true
        },
        trayDetailVisible(val) {
            if (!val) this.app.clearOutline();
        }
    },
    beforeUnmount() {
        if (this.kernel) {
            this.kernel.off('handleResources', this.handleResourcesFunc);
            this.kernel.off('handleIncrement', this.handleIncrementFunc);
        }
        if (this.running) clearTimeout(this.running);
    },
    created() {
        this.init();
    },
    methods: {
        cancelClick() {
            drawer.value = false
        },
        async init() {
            // let lo = Storage.getSessionStorage('TINYENGINE').get('SETTINGS');
            // if (lo) this.settings = lo;

            this.initKernel();

            this.app = App.getInstance();

            // let staticPath = '/static';
            // if (process.env.NODE_ENV === 'production') staticPath = '/' + process.env.VUE_APP_PROJECT_NAME + staticPath;
            // this.app.setStaticPath(staticPath);
            this.app.setStaticPath('');

            if (this.$root.resources.contours) this.app.updateContours(this.$root.resources.contours);
            if (this.$root.resources.paths) this.app.updatePaths(this.$root.resources.paths);
            // if (this.$root.resources.vehicles) this.app.updateVehicles(this.$root.resources.vehicles);
            // await this.app.loadModel('contours_1.glb', { x: -106000, y: 39000 }, 0.5);
            // await this.app.loadModel('contours_13.glb', { x: 215000, y: 112000 }, 0.20);
            // await this.app.loadModel('contours_17.glb', { x: 190000, y: 48000 }, 0.15);
            // await this.app.loadModel('contours_50.glb', { x: 160000, y: 127000 }, 1);
            // this.viewport = this.app.viewport;

            this.initTrayLifecycle();
        },
        initKernel() {
            console.log('map-3d.initKernel: ', this.$parent);
            this.kernel = Kernel.getInstance(this.$root);
            this.kernel.disconnect();
            this.kernel.initWorker(offlineWorker);
            // this.kernel.offlineConnect('logo', 1, mock.getLocalResources('logo'));
            this.kernel.offlineConnect('map', 50, mock.getLocalResources('map'), true);
            // this.kernel.offlineConnect('berth', 1000, mock.getLocalResources('berth'));
            // this.kernel.offlineConnect('offline', 1000, mock.getLocalResources('offline'));
            this.kernel.on('handleResources', this.handleResourcesFunc);
            this.kernel.on('handleIncrement', this.handleIncrementFunc);
        },
        handleResourcesFunc(res) {
            console.warn('map-3d.handleResourcesFunc: ', res);
            Object.keys(res.data).forEach(k => {
                k === 'contours' && this.app.createContours(res.data[k]);
                k === 'vehicles' && this.app.createVehicles(res.data[k]);
                k === 'paths' && this.app.createPaths(res.data[k]);
            });
            // if (res && res.data && res.data.vehicles && res.data.vehicles.length) this.tmpFollowVehicle = res.data.vehicles[0].id;
        },
        handleIncrementFunc(res) {
            // console.warn('map-3d.handleIncrementFunc: ', res);
            if (!res || !res.data || !res.data) return;
            // let vehicles = res.data.vehicles;
            // if (this.settings.vehicleDel) vehicles = res.data.vehicles.splice(1, 3);
            Object.keys(res.data).forEach(k => {
                k === 'contours' && this.app.updateContours(res.data[k]);
                k === 'vehicles' && this.app.updateVehicles(res.data[k]);
                k === 'paths' && this.app.updatePaths(res.data[k]);
                // k === 'vehicles' && this.app.updateVehicles(vehicles);
            });
            // if (!this.tmpFollowVehicle && res && res.data && res.data.vehicles && res.data.vehicles.length) this.tmpFollowVehicle = res.data.vehicles[0].id;
        },
        initTrayLifecycle() { // This’s a demo, replace a real content in a real project. 
            this.runTrayLifecycle();
        },
        async runTrayLifecycle() {
            if (this.running) clearTimeout(this.running);
            let res = await this.virtualGetTrayStatus();
            // console.log('map-3d.runTrayLifecycle.virtualGetTrayStatus: ', res.data);
            if (res && res.data && res.data.length) {
                res.data.forEach(s => {
                    if (this.app.isRunning()) this.app.setShelfStatus(s.id, s.status);
                });
            }
            this.running = setTimeout(this.runTrayLifecycle, 3000);
        },
        async virtualGetTrayStatus() { // This’s a random demo, replace a real api request in a real project.
            // Get all shelves from local resources, useless in real project.
            if (!this.shelves) this.shelves = [];
            if (!this.shelves.length && this.$root.resources.contours) {
                this.$root.resources.contours.forEach(c => {
                    if (c.m3d === 'item1.glb') this.shelves.push(c.id);
                });
            }
            let rtn = {
                status: 0,
                msg: '',
                data: []
            };
            let getListFn = () => {
                let r = [];
                for (let i = 0; i < 5; i++) {
                    r[i] = [];
                    for (let j = 0; j < 6; j++) {
                        r[i][j] = Math.floor(Math.random() * 2);
                    }
                }
                return r;
            };
            this.shelves.forEach(s => {
                rtn.data.push({
                    id: s,
                    status: getListFn()
                });
            });
            return new Promise(resolve => {
                setTimeout(() => resolve(rtn), 200);
            });
        },

        handleReset() {
            this.app.resetCamera();
        },
        handleDestory() {
            this.app.destory();
        },
        handleLabel(val) {
            // this.showLabels = !this.showLabels;
            // console.log
            Storage.getSessionStorage('TINYENGINE').set('showLabels', val);
            this.reload();
        },
        handleTarget() {
            console.log('map-3d.handleTarget: ', this.tmpFollowVehicle, this.followVehicle);
            this.followVehicle = this.followVehicle ? '' : this.tmpFollowVehicle;
            if (!this.followVehicle) this.handleReset();
        },
        handleTopViewChanged(val) {
            this.app.topViewChanged(val);
            this.reload();
        },
        handleRefreshStorage(val) {
            Storage.getSessionStorage('TINYENGINE').set('SETTINGS', null);
            this.reload();
        },
        handlePainting(args) {
            this.app.enableRotate(args === '');
            console.warn('---> ', args);
            if (args === GRAPH_TYPES.LINE) {
                this.app.handlePainting(args);
            }
        },
        pointerMoveCallback(res) {
            // if (res && res.length && !this.contoursCameraPos[res[0].name]) res = [];
            // console.warn('map-3d.pointerMoveCallback: ', res);
            // if (this.app.artist && this.app.artist.outlinePass) this.app.artist.outlinePass.selectedObjects = res;
        },
        clickCallback(mesh, instanceId, root) {
            let tray = this.app.getTrayByMesh(mesh, root);
            // console.log('map-3d.clickCallback: ', tray, mesh.instanceId);
            console.log('map-3d.clickCallback: ', tray, instanceId, mesh, root);
            if (!tray.id && tray.pid && this.contoursCameraPos[tray.pid]) {
                tray.x = tray.lx;
                tray.y = 10;
                tray.z = tray.lz + 10;
                this.app.moveCamera(_.cloneDeep({ ...tray }));
            }
            if (tray.id) {
                this.app.setOutline(mesh);
                this.getTrayDetail(tray.pid, tray.id);
            }
            //如果是道路
            if (mesh.userData && !mesh.userData.is3d && mesh.userData.properties.roadId){
                // this.app.setSelectedRoadContours(mesh.userData.properties.roadId);
                ElNotification.closeAll();
                let isSelected = this.app.setSelectedContours(mesh);
                // this.drawer = isSelected;
                if (isSelected){
                    this.handleShowElNotification(mesh.userData);
                    this.currRoadId = mesh.userData.properties.roadId;
                    this.currLaneId = mesh.userData.properties.laneId;
                }
            }
        },

        handleShowElNotification(userData) {
            let htmlMsg = "<font color='teal'>路段编号：" 
            + userData.properties.roadId
                + "<br>车道编号："
                + userData.properties.laneId
                + "</font>";
            ElNotification({
                title: '当前车道信息',
                dangerouslyUseHTMLString: true,
                // message: h('i', { style: 'color: teal' }, htmlMsg),
                message: htmlMsg,
                duration: 0,
            })
        },
        async getTrayDetail(shelfId, trayId) {
            let res = await this.getTrayDetailApi(shelfId, trayId);
            this.trayDetail.str = res;
            this.trayDetailVisible = true;
        },
        async getTrayDetailApi(shelfId, trayId) {
            let rtn = '货架：' + shelfId + '， 货位：' + trayId + '!!!';
            return new Promise(resolve => {
                setTimeout(() => resolve(rtn), 200);
            });
        },
        handleAnimations(act) {
            console.warn('map-3d.handleAnimations: ', act);
            // this.app.
        }
    }
};
</script>

<style lang="scss">
.page-map-3d {
    // width: 100%;
    // height: 100%;
    position: relative;
    width: 100vw;
    height: calc(100vh - 50px);

    // .three-container {
    //     // width: calc(100vw - 300px);
    //     // height: calc(100vh - 80px);
    //     width: 100%;
    //     height: 100%;
    //     box-shadow: 3px 3px 6px #cccccc;
    // }
    .btns {
        position: fixed;
        right: 20px;
        top: 60px;
        cursor: pointer;

        .icon {
            margin: 0 10px;
        }
    }
}

.dg {
    opacity: 0.95;
    // &.main {
    //     .close-button {
    //         background-color: #409eff;
    //         &:hover {
    //             background-color: #409eff;
    //         }
    //     }
    // }
}
.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.text {
    font-size: 14px;
}

.item {
    margin-bottom: 18px;
}

.box-card {
    width: 480px;
    position: relative;
}
</style>
